// ============================================
// IMPROVED GEMINI 2.5 PRO CONTENT GENERATOR v11.0 (FIXED)
// ============================================

// --- CONFIGURATION ---
const API_KEYS = [
  "AIzaSyDaTlIfAvE16d1tcUpYf36W2AvJLyvfpCA",
   "AIzaSyCX5cyvEMHNVmIhLyJy9k5F4gK3Z_12nRc",
  "AIzaSyAglH7ziQNK8tOBcfsq773rGsmyR0flG4g",
  "AIzaSyCfKsRAOzmQRTtEFNMBGXfjuK6-M9ZywJ0",
  "AIzaSyCk2sDgg1ZEz-y5hDROGtowZ9QCLHC8jVs",
  "AIzaSyDOKrEV4vF9uG8BV7oD-wDBDSmj2FnxoOQ",
  "AIzaSyCJhjc-5wDP7PPAki_7TAYtS4_9H4oBfMY",
  "AIzaSyAW-BUcALvA5XJ0yHPhIKRodi-RMfmxlUw",
  "AIzaSyBrM9nnTT7Jx_qmZztMGOYWI-aliQYsOAI",
  "AIzaSyChyd0s7vdQYoP6IMekoVoT5LWKfj8VVt4",
  "AIzaSyB-7H-96RTJFMOT0B-rb33IRQlRgCtOJQA",
  "AIzaSyCNBVH71NRmjB0DVQJrR5hU8y08ZNw0Qeo",
  "AIzaSyCGyIWP-uWnS_z2o9Fhjvp-Sn2h-Qtlkbc",
  "AIzaSyBJs5gIIGdKIQr3loHXlvuifs6P3ESmL0o",
  "AIzaSyC12QXQfJlYJCLIgui1HWZDvYJBx630MZ8",
  "AIzaSyCvRL9NFA3bnIR7vDLFz2kldlcow55C1BM",
  "AIzaSyADGc0k0iLYDi9C7V4SjicPGV_4rZXcGpk",
];

// Track which API key is currently in use
let currentKeyIndex = 0;

const CONFIG = {

  model: "gemini-flash-latest",
  version: "v1beta", 
  temperature: 0.7,
  top_p: 0.9,
  // Reduced max tokens for faster generation while maintaining quality
  maxOutputTokens: 64000,  // Reduced from 65000

  retryDelay: 1000 // 1 second delay between retries
};

const COLUMNS = {
  KEYWORD: 0, NLP_OUTLINE: 1, INTRO: 2, CONTENT: 3, 
  FAQS: 4, META_DESC: 5, TITLE: 6, SECONDARY_KEYWORD: 7
};

const CACHE_KEY_LOGS = 'GEMINI_EXEC_LOGS';
const CACHE_KEY_STATE = 'GEMINI_EXEC_STATE';

// --- MENU & UI ---

function onOpen() {
  SpreadsheetApp.getUi().createMenu('🚀 Advanced Content Generator')
    .addItem('📊 Open Advanced Sidebar', 'openAdvancedSidebar')
    .addItem('🗑️ Clear Cache/Reset', 'clearCacheAndState')
    .addToUi();
}

function openAdvancedSidebar() {
  const html = HtmlService.createHtmlOutput(getAdvancedSidebarHtml())
    .setTitle('🚀 Advanced Content Generator v11.0');
  SpreadsheetApp.getUi().showSidebar(html);
}

// ============================================
// REAL-TIME LOGGING & STATE MANAGEMENT (FIXED)
// ============================================

function addLog(message, level = 'info') {
  const cache = CacheService.getUserCache();
  const timestamp = new Date().toLocaleTimeString('en-US', { hour12: false });
  
  const logEntry = {
    timestamp: timestamp,
    level: level,
    message: message
  };

  // Get existing logs from cache
  let logs = [];
  const cachedLogs = cache.get(CACHE_KEY_LOGS);
  if (cachedLogs) {
    try { logs = JSON.parse(cachedLogs); } catch(e) {}
  }

  // Add new log and keep only last 40 to prevent Cache limits
  logs.push(logEntry);
  if (logs.length > 40) logs.shift();

  // Save back to cache (expires in 6 hours)
  cache.put(CACHE_KEY_LOGS, JSON.stringify(logs), 21600);
  
  // Also log to internal console for debugging
  console.log(`[${level.toUpperCase()}] ${message}`);
}

function getLogs() {
  const cache = CacheService.getUserCache();
  const cachedLogs = cache.get(CACHE_KEY_LOGS);
  return cachedLogs ? JSON.parse(cachedLogs) : [];
}

function clearLogs() {
  CacheService.getUserCache().remove(CACHE_KEY_LOGS);
}

function updateState(updates) {
  const cache = CacheService.getUserCache();
  let state = getProcessingStatus(); // Get current or default
  
  // Merge updates
  const newState = { ...state, ...updates };
  
  cache.put(CACHE_KEY_STATE, JSON.stringify(newState), 21600);
  return newState;
}

function getProcessingStatus() {
  const cache = CacheService.getUserCache();
  const cachedState = cache.get(CACHE_KEY_STATE);
  
  const defaultState = {
    isProcessing: false,
    currentTask: 'Idle',
    currentRow: 0,
    totalRows: 0,
    rowsCompleted: 0,
    progress: 0,
    currentKeyword: ''
  };

  if (cachedState) {
    try { return JSON.parse(cachedState); } catch(e) { return defaultState; }
  }
  return defaultState;
}

function clearCacheAndState() {
  const cache = CacheService.getUserCache();
  cache.remove(CACHE_KEY_LOGS);
  cache.remove(CACHE_KEY_STATE);
  addLog('Cache cleared. Ready to start.', 'info');
}

// ============================================
// ROW MANAGEMENT
// ============================================

function getAvailableRows() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const lastRow = sheet.getLastRow();
  const availableRows = [];

  // Assuming headers are in row 1, data starts row 2
  if (lastRow < 2) return [];

  const data = sheet.getRange(2, 1, lastRow - 1, 8).getValues();

  for (let i = 0; i < data.length; i++) {
    const rowNum = i + 2; // Actual sheet row number
    if (data[i][0] && data[i][0].toString().trim() !== "") {
      availableRows.push({
        row: rowNum,
        keyword: data[i][0].toString(),
        secondaryKeyword: data[i][7] ? data[i][7].toString() : "",
        nlpOutline: data[i][1] ? data[i][1].toString() : ""
      });
    }
  }
  return availableRows;
}

// ============================================
// CORE GENERATION LOGIC
// ============================================

function startGeneration(selectedRows) {
  // Reset logs and state at start
  clearCacheAndState();
  
  if (!selectedRows || selectedRows.length === 0) {
    return { success: false, message: 'No rows selected' };
  }

  updateState({
    isProcessing: true,
    totalRows: selectedRows.length,
    rowsCompleted: 0,
    progress: 0,
    currentTask: 'Starting initialization...'
  });

  addLog(`🚀 Starting generation for ${selectedRows.length} rows`, 'info');

  // We loop here. In a pro script, we might use Triggers for very long lists,
  // but for <10 rows, a simple loop works if we keep it under 6 mins.
  try {
    processBatch(selectedRows);
    return { success: true, message: 'Batch completed successfully' };
  } catch (e) {
    addLog(`💥 Critical Error: ${e.toString()}`, 'error');
    updateState({ isProcessing: false, currentTask: 'Error Stopped' });
    return { success: false, message: e.toString() };
  }
}

function processBatch(rowNumbers) {
  const sheet = SpreadsheetApp.getActiveSheet();
  
  for (let i = 0; i < rowNumbers.length; i++) {
    const rowNum = rowNumbers[i];
    const rowData = getRowData(rowNum);
    
    // Update State
    updateState({
      currentRow: rowNum,
      currentKeyword: rowData.keyword,
      progress: Math.round((i / rowNumbers.length) * 100),
      currentTask: `Processing Row ${rowNum}: ${rowData.keyword}`
    });

    addLog(`📍 START ROW ${rowNum}: "${rowData.keyword}"`, 'info');

    // Create a results object to store all generated content
    const results = {
      intro: null,
      content: null,
      faqs: null,
      meta: null,
      title: null
    };

    // 1. TITLE - Generate first as it might influence other content
    addLog(`⏳ Generating Title...`, 'info');
    results.title = generateTitle(rowData);
    if (results.title) {
      sheet.getRange(rowNum, COLUMNS.TITLE + 1).setValue(results.title);
      addLog(`✅ Title Saved`, 'success');
    } else {
      addLog(`❌ Failed to generate Title`, 'error');
    }

    // 2. INTRO
    addLog(`⏳ Generating Intro...`, 'info');
    results.intro = generateHTMLIntro(rowData, results.title);
    if (results.intro) {
        sheet.getRange(rowNum, COLUMNS.INTRO + 1).setValue(results.intro);
        addLog(`✅ Intro Saved`, 'success');
    } else {
        addLog(`❌ Failed to generate Intro`, 'error');
    }

    // 3. CONTENT
    addLog(`⏳ Generating Main Content (Long Form)...`, 'info');
    results.content = generateHTMLContent(rowData, results.intro, results.title);
    if (results.content) {
        sheet.getRange(rowNum, COLUMNS.CONTENT + 1).setValue(results.content);
        addLog(`✅ Content Saved (${results.content.split(' ').length} words)`, 'success');
    } else {
        addLog(`❌ Failed to generate Content`, 'error');
    }

    // 4. FAQS
    addLog(`⏳ Generating FAQs...`, 'info');
    results.faqs = generateHTMLFAQs(rowData, results.content);
    if (results.faqs) {
        sheet.getRange(rowNum, COLUMNS.FAQS + 1).setValue(results.faqs);
        addLog(`✅ FAQs Saved`, 'success');
    } else {
        addLog(`❌ Failed to generate FAQs`, 'error');
    }

    // 5. META DESC
    addLog(`⏳ Generating Meta Description...`, 'info');
    results.meta = generateMetaDescription(rowData, results.content, results.title);
    if (results.meta) {
        sheet.getRange(rowNum, COLUMNS.META_DESC + 1).setValue(results.meta);
        addLog(`✅ Meta Description Saved`, 'success');
    } else {
        addLog(`❌ Failed to generate Meta Description`, 'error');
    }

    // Check if any part failed
    const failedParts = Object.keys(results).filter(key => !results[key]);
    if (failedParts.length > 0) {
      addLog(`⚠️ Row ${rowNum} completed with missing parts: ${failedParts.join(', ')}`, 'warning');
    } else {
      addLog(`🎉 Row ${rowNum} Complete - All parts generated successfully`, 'success');
    }

    // Update completion
    updateState({ rowsCompleted: i + 1 });
  }

  updateState({ 
    isProcessing: false, 
    progress: 100, 
    currentTask: 'All Tasks Completed' 
  });
  addLog('🏁 Batch Generation Finished', 'success');
}

function getRowData(rowNum) {
  const sheet = SpreadsheetApp.getActiveSheet();
  const row = sheet.getRange(rowNum, 1, 1, 8).getValues()[0];
  return {
    keyword: row[0],
    nlpOutline: row[1],
    secondaryKeyword: row[7]
  };
}

// ============================================
// GEMINI API CALLS (FIXED)
// ============================================

// Get the next API key in round-robin fashion
function getNextApiKey() {
  const key = API_KEYS[currentKeyIndex];
  currentKeyIndex = (currentKeyIndex + 1) % API_KEYS.length;
  return key;
}

// Reset API key index to start from the first key
function resetApiKeyIndex() {
  currentKeyIndex = 0;
}
function callAdvancedGeminiApi(prompt, systemPrompt, taskType) {
  let attempts = 0;
  const maxAttempts = API_KEYS.length;
  
  // Reset to start with the first key
  resetApiKeyIndex();

  while (attempts < maxAttempts) {
    try {
      const apiKey = getNextApiKey();
      addLog(`🔑 Using API key index ${currentKeyIndex} for ${taskType}`, 'info');
      
      // Construct Endpoint for Gemini
      const url = `https://generativelanguage.googleapis.com/${CONFIG.version}/models/${CONFIG.model}:generateContent?key=${apiKey}`;


      // Construct Payload with Tools and Thinking Config
      const payload = {
        systemInstruction: {
          parts: [{ text: systemPrompt || 'You are a world-class SEO strategist, copywriter, and knowledge systems engineer with 32 years of experience. You create long-form, Semantic google HCS , authoritative search-first, semantically optimized content. Every output must demonstrate topical authority, E-E-A-T signals, and deliver authentic, knowledge-rich' }]
        },
        contents: [
          { 
            role: "user", 
            parts: [{ text: prompt }] 
          }
        ],
        // Add Google Search Tool
        tools: [
          { 
            googleSearch: {} 
          }
        ],
        generationConfig: {
          temperature: CONFIG.temperature,
          maxOutputTokens: CONFIG.maxOutputTokens,
          // Add Thinking Config (Budget -1 implies auto/max)
          thinkingConfig: {
            thinkingBudget: 2000
          }
        }
      };

      const response = UrlFetchApp.fetch(url, {
        method: "post",
        contentType: "application/json",
        payload: JSON.stringify(payload),
        muteHttpExceptions: true
      });

      const responseCode = response.getResponseCode();
      const responseText = response.getContentText();

      if (responseCode !== 200) {
        addLog(`API Error ${responseCode}: ${responseText}`, 'error');
        
        // If rate limited, try with next key
        if (responseCode === 429) {
          addLog(`Rate limited on key index ${currentKeyIndex}, trying next key`, 'warning');
          attempts++;
          continue;
        }
        
        // For other errors, also try next key
        attempts++;
        continue;
      }

      const json = JSON.parse(responseText);
      if (json.candidates && json.candidates[0].content) {
        addLog(`✅ Successfully generated ${taskType}`, 'success');
        return json.candidates[0].content.parts[0].text;
      } else {
        addLog(`Invalid response format for ${taskType}`, 'error');
        attempts++;
      }
    } catch (e) {
      addLog(`API Exception for ${taskType}: ${e.toString()}`, 'error');
      attempts++;
    }
    
    // Add delay between retries
    if (attempts < maxAttempts) {
      Utilities.sleep(CONFIG.retryDelay);
    }
  }
  
  addLog(`❌ All API keys exhausted for ${taskType}`, 'error');
  return null;
}
// ============================================
// PROMPT FUNCTIONS (FIXED)
// ============================================

function generateHTMLIntro(data, title) {
  const sys = `You are an  SEO content writer with 20+ years of experience. Write EXACTLY two introduction paragraphs each paragraph between only 150-200 words. Each paragraph MUST start DIRECTLY with the primary keyword - no articles or filler phrases inclose in p tag.
  ${title ? `The title is: "${title}".` : ''}


EXPERTISE AREAS:
- Semantic SEO and keyword integration in HTML
- User intent analysis and matching
- Authority building through expert language
- Compelling storytelling techniques
- Strict HTML formatting with allowed tags only
- Do not use * or ** symbols.
`;


  const prompt = `Write a 2-paragraph intro for "${data.keyword}". Include secondary keyword: "${data.secondaryKeyword}". 
 
As a pro seo expert generate  introduction two parapgraph that:
Tone: Maintain a professional yet accessible tone, balancing authority with simplicity. Ensure the language is clear and easy to understand for a general audience (Grade level 7-9)
   - Naturally integrates all keywords at appropriate density without stuffing.
   - Focus Keyphrase (Choose a Focus Keyphrase, Use it in Key Positions )
   - Keyword Optimization (se the Focus Keyword Naturally, LSI Keywords)
   - Covers all relevant subtopics, examples, and related entities for full semantic coverage.
   - Demonstrates authority and expertise (E-E-A-T).
   - Follow Google’s SEO Guidelines For better Content, ensuring the information is valuable and helpful according to user needs, and free of unnecessary content or filler.
   - Ensure the output is free of grammar or spelling errors while maintaining readability Easy to Read.
   - Ensure content remains to the point, focused, and easy to understand words-sentence. make sure each sentence easy to understand clear which have proper meaning, aligning with user intent. - - - Avoid unnecessary expansions, keeping the content easy to understand and use short sentence for better readability.

1. STARTS with the primary keyword naturally in the first sentence
2. Incorporates the secondary keyword naturally 
3. Addresses user intent and pain points related to man keyword "${data.keyword}".
4. Establishes authority and credibility
5. Creates curiosity and provides value upfront
All content must directly solve user problems
Write the content without using AI-style filler words or patterns.  
Do not use wording that sounds generic, repetitive, or machine-generated.  
Avoid the following categories completely:  
– general filler (accurate, comprehensive, detailed, overview, typically, usually, generally)  
– vague verbs (provide, provided, offering, allows, allow)  
– weak structure words (process, method, option, tool, resources)  
– unnecessary formality (context, insight, profile, records maintained by, repository)  
– content-padding phrases (listed below, as follows, various, multiple, including, contains) .

Strictly follow this requirement: your response should not include any of the following words and phrases: meticulous, meticulously, navigating, complexities, realm, understanding, dive, shall, tailored, towards, underpins, everchanging, ever-evolving, the world of, not only, alright, embark, Journey, In today's digital age, hey, game changer, designed to enhance, it is advisable, daunting, when it comes to, in the realm of, amongst, unlock the secrets, unveil the secrets, and robust, diving, elevate, unleash, power, cutting-edge, rapidly, expanding, mastering, excels, harness, imagine, It's important to note, Delve into, Tapestry, Bustling, In summary, Remember that…, Take a dive into, Navigating, Landscape, Testament, In the world of, Realm, Embark, Analogies to being a conductor or to music, Vibrant, Metropolis, Firstly, Moreover, Crucial, To consider, Essential, There are a few considerations, Ensure, It's essential to, Furthermore, Vital, Keen, Fancy, As a professional, However, Therefore, Additionally, Specifically, Generally, Consequently, Importantly, Indeed, Thus, Alternatively, Notably, As well as, Despite, Essentially, While, Unless, Also, Even though, Because, In contrast, Although, In order to, Due to, Even if, Given that, Arguably, You may want to, On the other hand, As previously mentioned, It's worth noting that, To summarize, Ultimately, To put it simply, Promptly, Dive into, In today's digital era, Reverberate, Enhance, Emphasize / Emphasize, Revolutionize, Foster, Remnant, Subsequently, Nestled, Game changer, Labyrinth, Gossamer, Enigma, Whispering, Sights unseen, Sounds unheard, Indelible, My friend, In conclusion, guide, guidelines, addition, era, individuals, Definitive. Guide.



CONTENT STRUCTURE TO REFERENCE:
${data.nlpOutline}

Generate ONLY the well seo optimze 2 intro paragragh in html p tag.):
  Start directly with the keyword.`;
  return cleanHTML(callAdvancedGeminiApi(prompt, sys, 'Intro'));
}



/// Content Genenration prompts#################################

function generateHTMLContent(data, intro, title) {
  const sys = `You are a world-class SEO strategist, copywriter, and knowledge systems engineer with 32 years of experience.
You create long-form, search-first, semantically optimized content that starts with the main keyword in the first sentence or heading.
Every output must demonstrate topical authority, E-E-A-T signals, and deliver authentic, knowledge-rich value between 3500-4500 words. make sure give me complete content not skip or stop without complete the content.
You never generate fluff, repetitive sentences, or keyword stuffing.
 Strictly follow this requirement: your response should not include any of the following words and phrases:  Definitive, Alternative meticulous, meticulously, navigating, complexities, realm, understanding, dive, shall, tailored, towards, underpins, everchanging, ever-evolving, the world of, not only, alright, embark, Journey, In today's digital age, hey, game changer, designed to enhance, it is advisable, daunting, when it comes to, in the realm of, amongst, unlock the secrets, unveil the secrets, and robust, diving, elevate, unleash, power, cutting-edge, rapidly, expanding, mastering, excels, harness, imagine, It's important to note, Delve into, Tapestry, Bustling, In summary, Remember that…, Take a dive into, Navigating, Landscape, Testament, In the world of, Realm, Embark, Analogies to being a conductor or to music, Vibrant, Metropolis, Firstly, Moreover, Crucial, To consider, Essential, There are a few considerations, Ensure, It's essential to, Furthermore, Vital, Keen, Fancy, As a professional, However, Therefore, Additionally, Specifically, Generally, Consequently, Importantly, Indeed, Thus, Alternatively, Notably, As well as, Despite, Essentially, While, Unless, Also, Even though, Because, In contrast, Although, In order to, Due to, Even if, Given that, Arguably, You may want to, On the other hand, As previously mentioned, It's worth noting that, To summarize, Ultimately, To put it simply, Promptly, Dive into, In today's digital era, Reverberate, Enhance, Emphasize / Emphasize, Revolutionize, Foster, Remnant, Subsequently, Nestled, Game changer, Labyrinth, Gossamer, Enigma, Whispering, Sights unseen, Sounds unheard, Indelible, My friend, In conclusion, guide, guidelines, addition, era, individuals, Definitive. Guide, Comprehensive, in addition, conclusion, final thought, final word, inshort, Accessing, Differentiating, extensive, signifies, enforcement, information, info, informative etc.
All content should be structured with H1, H2, H3, H4, and FAQs as relevant, and written at a 5th-grade reading level for clarity..
SPECIALIZATIONS:
- Semantic keyword integration and LSI optimization in HTML
- E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness)
- User intent mapping and satisfaction
- Technical accuracy with practical applications
- Conversion-optimized content structure with visual engagement
- Do not add faqs in this content
- Make sure add real offical detail not own wrong add
- Do not use * or ** symbols.

As a world-class SEO strategist, copywriter, and knowledge systems engineer with 32 years of experience. Make sure this is not a guide but did not use word like this info this gudie, guide etc anywhere in content.


SPECIALIZATIONS:
- Semantic keyword integration and LSI optimization in HTML
- E-E-A-T (Experience, Expertise, Authoritativeness, Trustworthiness)
- User intent mapping and satisfaction
- Technical accuracy with practical applications
- Conversion-optimized content structure
- STRICT HTML formatting with allowed tags only
- Do not add any fake info anywhere in content`;



  const prompt = `Your only goal: Create a HIGH-ENGAGEMENT, SEO-DOMINANT content piece (3500-4500 words) that users love to read and Google prioritizes for ranking start with h2 heading. ake sure give me complete content not skip or stop without complete the content.

  

Analyze the following inputs:
PRIMARY KEYWORD: "${data.keyword}"
SECONDARY KEYWORD: "${data.secondaryKeyword || 'N/A'}"
NLP/LSI OUTLINE: "${data.nlpOutline}"
INTRODUCTION: "${intro}"
  ${title ? `Title: "${title}".` : ''}
  ${intro ? `Existing Intro: ${intro}.` : ''}
Generate a COMPREHENSIVE, PRODUCTION-READY SEO page content  (3000-4500 words) in STRICT HTML format:
CONTENT STRUCTURE REQUIREMENTS (MANDATORY):

CRITICAL REQUIREMENTS:
do add intor 
1. srictly start with H2 heading that includes the primary keyword.
2. EXCLUDE these phrases: "question:", "conclusion:", "intro", "final thought:", "in conclusion:", "to conclude:", "ultimately:", "finally,", "lastly," "FAQ's into"
4. Main H2 heading with keyword
5. 3500-5000 words total
6. Use heading paragraph list table to make the content engaingin and tractive to attract user with best main heading sould be h2
7. Real office location contact block, emails and phone numbers
8. Embedded Google Maps iframe
9. Real resources, PDFs, dates, prices
10. Use real value price date etc where need and valuable, help the user

1. VISUAL ENGAGEMENT FORMULA:
   - USE Lists (ul/ol) and Tables for maximum readability
   - Maximum 2-3 sentences per paragraph
   - Break content with subheadings every 120-150 words
   - Use numbered lists for processes and rankings
   - Create comparison tables for options, tools, methods
   - Do not use * or ** symbols.
Paragraphs max 120–150 words
Sentences avg 20 words or fewer
30%+ transition words
Active voice heavily preferred
Keyword + entities placed in key positions (H1, H2, first 100 words, summaries)
Subheadings every 120–200 words
Scannable formatting: lists, bullets, steps, pros/cons, FAQs
All content must directly solve user problems
Write the content without using AI-style filler words or patterns.  
Do not use wording that sounds generic, repetitive, or machine-generated.  




CONTENT REQUIREMENTS:
Produce a new SEO-optimized  a well-optimized, user-focused content piece that is not only tailored to ranking high on search engines but also provides significant value to the user, making it difficult to de-rank in the long run and content word cout stickly between  (3500-4500 words) that:
   - Follows a hierarchical structure: H1 (title), H2 for main sections, H3/H4 for subtopics ul/ol for list, , <table> for best layout table if need.
   - Paragraphs max 120–150 words
   - Sentences avg 20 words or fewer
   - 30%+ transition words
   - Active voice heavily preferred
   - Keyword + entities placed in key positions (H1, H2, first 100 words, summaries)
   - Scannable formatting: lists, bullets, steps, pros/cons, FAQs
   - All content must directly solve user problems
   - content without using AI-style filler words or patterns.  
   - Do not use wording that sounds generic, repetitive, or machine-generated.  
   - Short Paragraphs: Keep paragraphs under 150 words for readability and user experience.
   - Tone: Maintain a professional yet accessible tone, balancing authority with simplicity. Ensure the language is clear and easy to understand for a general audience (Grade level 7-9)
   - Naturally integrates all keywords at appropriate density without stuffing.
   - Focus Keyphrase (Choose a Focus Keyphrase, Use it in Key Positions )
   - Keyword Optimization (se the Focus Keyword Naturally, LSI Keywords)
   - Covers all relevant subtopics, examples, and related entities for full semantic coverage.
   - Demonstrates authority and expertise (E-E-A-T).
   - Follow Google’s SEO Guidelines For better Content, ensuring the information is valuable and helpful according to user needs, and free of unnecessary content or filler.
   - Ensure the output is free of grammar or spelling errors while maintaining readability Easy to Read.
   - Ensure content remains to the point, focused, and easy to understand words-sentence. make sure each sentence easy to understand clear which have proper meaning, aligning with user intent. - - - Avoid unnecessary expansions, keeping the content easy to understand and use short sentence for better readability.
   - Contains a 5–7 question FAQ section addressing common or strategic user questions make sure faq section main heading have pargraph 3-4 lines.
   - Optionally suggests meta title, meta description, and internal links.
   - Add real and authentic info value 
   - In last before faq section  Add offical website link(not clickable), phone number, visiting hours 
✓ Do not alter any heading levels. Every H2 must remain an H2, and every H3 must remain an H3. Preserve the exact markdown structure. And Heading should be in Bold.

HTML TAGS ONLY: <h2>, <h3>, <h4>, <p>, <strong>, <b>, <em>, <i>, <a>, <table>, <tr>, <td>, <th>, <ul>, <li>, <ol>, <br>, <iframe>

Avoid the following categories completely:  
– general filler (accurate, comprehensive, detailed, overview, typically, usually, generally)  
– vague verbs (provide, provided, offering, allows, allow)  
– weak structure words (process, method, option, tool, resources)  
– unnecessary formality (context, insight, profile, records maintained by, repository)  
– content-padding phrases (listed below, as follows, various, multiple, including, contains)
- now conclustion no faqs anywere



3. Rules for output:
   - Prioritize user intent behind each keyword.
   - Avoid shallow repetition; each paragraph must add unique, high-value information.
   - Use clear, concise, trust-building language.
   - Ensure semantic SEO: cover related concepts, synonyms, entities, and context.
   - Start content with the main keyword and phrase naturally in the first 50 words.
   - Format headings clearly; no empty sections.
Outline STRUCTURE TO FOLLOW EXACTLY:
${data.nlpOutline}

CONTENT SECTIONS TO INCLUDE:
1. Comprehensive introduction (building on provided intro)
2. Main content following NLP outline structure
3. Detailed sections addressing user pain points
4. Practical examples and real-world applications
5. Current industry trends and updates
6. Expert recommendations and best practices
7. Contact information and location details map
8. Embedded Google Maps iframe center align

  The content must provide genuine value, use strategic visual structuring with tables where appropriate, and include the required Google Maps embedding at the end.`;
  return cleanHTML(callAdvancedGeminiApi(prompt, sys, 'Content'));
}

function generateHTMLFAQs(data, content) {
  const sys = `You are an expert FAQ strategist and SEO specialist who creates comprehensive, user-focused FAQ sections that rank in featured snippets and answer real user questions.
ou never generate fluff, repetitive sentences, or keyword stuffing in html tags stricky. 
 Strictly follow this requirement: your response should not include any of the following words and phrases:  Definitive, Alternative meticulous, meticulously, navigating, complexities, realm, understanding, dive, shall, tailored, towards, underpins, everchanging, ever-evolving, the world of, not only, alright, embark, Journey, In today's digital age, hey, game changer, designed to enhance, it is advisable, daunting, when it comes to, in the realm of, amongst, unlock the secrets, unveil the secrets, and robust, diving, elevate, unleash, power, cutting-edge, rapidly, expanding, mastering, excels, harness, imagine, It's important to note, Delve into, Tapestry, Bustling, In summary, Remember that…, Take a dive into, Navigating, Landscape, Testament, In the world of, Realm, Embark, Analogies to being a conductor or to music, Vibrant, Metropolis, Firstly, Moreover, Crucial, To consider, Essential, There are a few considerations, Ensure, It's essential to, Furthermore, Vital, Keen, Fancy, As a professional, However, Therefore, Additionally, Specifically, Generally, Consequently, Importantly, Indeed, Thus, Alternatively, Notably, As well as, Despite, Essentially, While, Unless, Also, Even though, Because, In contrast, Although, In order to, Due to, Even if, Given that, Arguably, You may want to, On the other hand, As previously mentioned, It's worth noting that, To summarize, Ultimately, To put it simply, Promptly, Dive into, In today's digital era, Reverberate, Enhance, Emphasize / Emphasize, Revolutionize, Foster, Remnant, Subsequently, Nestled, Game changer, Labyrinth, Gossamer, Enigma, Whispering, Sights unseen, Sounds unheard, Indelible, My friend, In conclusion, guide, guidelines, addition, era, individuals, Definitive. Guide, Comprehensive, in addition, conclusion, final thought, final word, inshort, Accessing, Differentiating, extensive, signifies, enforcement, information, info, informative etc.
All content should be structured with H1, H2, H3, H4, and FAQs as relevant, and written at a 5th-grade reading level for clarity.


EXPERTISE:
- User intent analysis and question research
- Featured snippet optimization
- Semantic keyword integration in HTML Q&A format
- Conversational yet professional tone
- Actionable, detailed answers
- STRICT HTML formatting with allowed tags only h2 h4 p`;



  const prompt = `PRIMARY KEYWORD: "${data.keyword}"
SECONDARY KEYWORD: "${data.secondaryKeyword || 'N/A'}"
 Content snippet: ${content ? content.substring(0,500) : 'No content available'}

Create a comprehensive FAQ section in STRICT HTML format with EXACTLY 5-6 strategic questions:

FAQ STRATEGY:
1. Primary keyword-focused questions (2-3 questions)
2. Secondary keyword variations (1-2 questions)  
3. Long-tail question variations (2-3 questions)
4. Problem/solution focused questions (1-2 questions)
Apply all of the following:

Paragraphs max 120–150 words
Sentences avg 20 words or fewer
30%+ transition words
Active voice heavily preferred
Keyword + entities placed in key positions (H1, H2, first 100 words, summaries)
Subheadings every 120–200 words
Scannable formatting: lists, bullets, steps, pros/cons, FAQs
All content must directly solve user problems
Write the content without using AI-style filler words or patterns.  
Do not use wording that sounds generic, repetitive, or machine-generated.  
Avoid the following categories completely:  
– general filler (accurate, comprehensive, detailed, overview, typically, usually, generally)  
– vague verbs (provide, provided, offering, allows, allow)  
– weak structure words (process, method, option, tool, resources)  
– unnecessary formality (context, insight, profile, records maintained by, repository)  
– content-padding phrases (listed below, as follows, various, multiple, including, contains) .

STRICT HTML FORMAT REQUIREMENTS:
<h2>Frequently Asked Questions</h2>
<p>Comprehensive introduction paragraph about ${data.keyword} services, benefits, and importance to users...</p>
<h3>[Specific question with natural keyword integration?]</h3>
<p>Detailed 75-120 word answer with specific examples, benefits, steps, or actionable advice...</p>
<h3>[Another strategic question?]</h3>
<p>Comprehensive answer with practical information and real-world applications...</p>
[Continue for 6-8 total questions]



CONTENT REQUIREMENTS:
✓ EXACTLY 5-6 questions total
✓ Each question naturally includes primary or secondary keywords
✓ Each answer 75-120 words with specific, actionable information
✓ Include real examples, steps, benefits, or processes
✓ Professional, helpful, and authoritative tone
✓ Address actual user concerns and search intents
✓ NO quotation marks in output
✓ Designed for featured snippet optimization

Generate ONLY the HTML content (no explanations, no quotes, just HTML):`;
  return cleanHTML(callAdvancedGeminiApi(prompt, sys, 'FAQs'));
}

function generateMetaDescription(data, content, title) {
  const sys = `You are a top-tier SEO specialist and conversion copywriter who crafts high-CTR meta descriptions that drive clicks and improve search performance. You excel at balancing keyword optimization with compelling, curiosity-driven language ou never generate fluff, repetitive sentences, or keyword stuffing. 
 Strictly follow this requirement: your response should not include any of the following words and phrases:  Definitive, Alternative meticulous, meticulously, navigating, complexities, realm, understanding, dive, shall, tailored, towards, underpins, everchanging, ever-evolving, the world of, not only, alright, embark, Journey, In today's digital age, hey, game changer, designed to enhance, it is advisable, daunting, when it comes to, in the realm of, amongst, unlock the secrets, unveil the secrets, and robust, diving, elevate, unleash, power, cutting-edge, rapidly, expanding, mastering, excels, harness, imagine, It's important to note, Delve into, Tapestry, Bustling, In summary, Remember that…, Take a dive into, Navigating, Landscape, Testament, In the world of, Realm, Embark, Analogies to being a conductor or to music, Vibrant, Metropolis, Firstly, Moreover, Crucial, To consider, Essential, There are a few considerations, Ensure, It's essential to, Furthermore, Vital, Keen, Fancy, As a professional, However, Therefore, Additionally, Specifically, Generally, Consequently, Importantly, Indeed, Thus, Alternatively, Notably, As well as, Despite, Essentially, While, Unless, Also, Even though, Because, In contrast, Although, In order to, Due to, Even if, Given that, Arguably, You may want to, On the other hand, As previously mentioned, It's worth noting that, To summarize, Ultimately, To put it simply, Promptly, Dive into, In today's digital era, Reverberate, Enhance, Emphasize / Emphasize, Revolutionize, Foster, Remnant, Subsequently, Nestled, Game changer, Labyrinth, Gossamer, Enigma, Whispering, Sights unseen, Sounds unheard, Indelible, My friend, In conclusion, guide, guidelines, addition, era, individuals, Definitive. Guide, Comprehensive, in addition, conclusion, final thought, final word, inshort, Accessing, Differentiating, extensive, signifies, enforcement, information, info, informative etc.
All content should be structured with H1, H2, H3, H4, and FAQs as relevant, and written at a 5th-grade reading level for clarity..

EXPERTISE:
- High click-through rate optimization
- Keyword placement and density
- Curiosity and benefit-driven language
- Character count precision
- Emotional triggers and psychological persuasion
- Competitive advantage messaging`;



  const prompt = `Keyword: ${data.keyword}. 
  SECONDARY KEYWORD: "${data.secondaryKeyword || 'N/A'}"
CONTENT SUMMARY: "${content.substring(0, 300)}..."
 ${title ? `Title: "${title}".` : ''}
  
Create a HIGH-CONVERTING meta description (EXACTLY 155-160 characters):

OPTIMIZATION STRATEGY:
1. Start with primary keyword within first 3-5 words
2. Include secondary keyword naturally
3. Create curiosity gap or specific benefit
4. Include action-oriented language
5. Suggest value or solution

CHARACTER REQUIREMENTS:
✓ EXACTLY 155-160 characters (count every space and punctuation)
✓ Primary keyword: "${data.keyword}" within first 5 words
✓ Secondary keyword: "${data.secondaryKeyword || 'variation'}" integrated naturally
✓ Compelling benefit or curiosity trigger
✓ Action-oriented or solution-focused language
✓ Professional, trustworthy tone
✓ NO quotation marks
✓ NO HTML TAGS

Generate ONLY the meta description text (155-160 chars, no quotes, no HTML):`;
  return callAdvancedGeminiApi(prompt, sys, 'Meta Description');
}

function generateTitle(data) {
  const sys = `You are an SEO title optimization expert and conversion copywriter who creates high-ranking, high-converting titles that dominate search results. You understand search intent, keyword placement, and psychological triggers that drive clicks ou never generate fluff, repetitive sentences, or keyword stuffing. 
 Strictly follow this requirement: your response should not include any of the following words and phrases:  Definitive, Alternative meticulous, meticulously, navigating, complexities, realm, understanding, dive, shall, tailored, towards, underpins, everchanging, ever-evolving, the world of, not only, alright, embark, Journey, In today's digital age, hey, game changer, designed to enhance, it is advisable, daunting, when it comes to, in the realm of, amongst, unlock the secrets, unveil the secrets, and robust, diving, elevate, unleash, power, cutting-edge, rapidly, expanding, mastering, excels, harness, imagine, It's important to note, Delve into, Tapestry, Bustling, In summary, Remember that…, Take a dive into, Navigating, Landscape, Testament, In the world of, Realm, Embark, Analogies to being a conductor or to music, Vibrant, Metropolis, Firstly, Moreover, Crucial, To consider, Essential, There are a few considerations, Ensure, It's essential to, Furthermore, Vital, Keen, Fancy, As a professional, However, Therefore, Additionally, Specifically, Generally, Consequently, Importantly, Indeed, Thus, Alternatively, Notably, As well as, Despite, Essentially, While, Unless, Also, Even though, Because, In contrast, Although, In order to, Due to, Even if, Given that, Arguably, You may want to, On the other hand, As previously mentioned, It's worth noting that, To summarize, Ultimately, To put it simply, Promptly, Dive into, In today's digital era, Reverberate, Enhance, Emphasize / Emphasize, Revolutionize, Foster, Remnant, Subsequently, Nestled, Game changer, Labyrinth, Gossamer, Enigma, Whispering, Sights unseen, Sounds unheard, Indelible, My friend, In conclusion, guide, guidelines, addition, era, individuals, Definitive. Guide, Comprehensive, in addition, conclusion, final thought, final word, inshort, Accessing, Differentiating, extensive, signifies, enforcement, information, info, informative etc.
All content should be structured with H1, H2, H3, H4, and FAQs as relevant, and written at a 5th-grade reading level for clarity..

SPECIALIZATIONS:
- High-ranking title optimization
- Keyword placement and density
- Emotional and psychological triggers
- Competitive differentiation
- Click-through rate optimization
- Brand authority and trust signals`;


  const prompt = `Keyword: ${data.keyword}. 
  SECONDARY KEYWORD: "${data.secondaryKeyword || 'N/A'}"

Create a HIGH-CONVERTING, HIGH-RANKING SEO title (55-60 characters):

TITLE OPTIMIZATION:
1. Primary keyword at beginning or within first 2-3 words
2. Strong, specific modifiers (avoid generic words)
3. Emotional or benefit-driven language
4. Professional credibility signals
5. Natural, readable flow

CHARACTER REQUIREMENTS:
✓ 55-60 characters EXACTLY (count every character)
✓ Primary keyword: "${data.keyword}" at start or within first 3 words
✓ Secondary keyword: "${data.secondaryKeyword || 'variation'}" integrated naturally
✓ Powerful, specific modifiers (NOT "ultimate", "complete", etc.)
✓ Professional, authoritative tone
✓ High click-through potential
✓ NO keyword stuffing
✓ Natural language flow
✓ NO HTML TAGS

Generate ONLY the title text (55-60 chars, no quotes, no HTML):`;
  return callAdvancedGeminiApi(prompt, sys, 'Title');
}

function cleanHTML(text) {
  if (!text) return "";
  // Remove markdown code blocks if Gemini adds them
  return text.replace(/```html/g, '').replace(/```/g, '').trim();
}

function stopGeneration() {
    updateState({ isProcessing: false, currentTask: 'Stopped by User' });
    addLog('🛑 Process Stopped', 'warning');
}

// ============================================
// SIDEBAR HTML (NO CHANGES NEEDED)
// ============================================

function getAdvancedSidebarHtml() {
  return `
<!DOCTYPE html>
<html>
<head>
  <base target="_top">
  <style>
    body { font-family: 'Segoe UI', Roboto, sans-serif; padding: 10px; background: #f3f4f6; color: #1f2937; }
    .card { background: white; border-radius: 8px; padding: 15px; margin-bottom: 10px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
    .header { font-weight: bold; color: #7c3aed; margin-bottom: 5px; font-size: 14px; text-transform: uppercase; }
    .btn { width: 100%; padding: 10px; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; margin-bottom: 5px; }
    .btn-primary { background: #7c3aed; color: white; }
    .btn-primary:disabled { background: #d1d5db; cursor: not-allowed; }
    .btn-stop { background: #ef4444; color: white; }
    
    .log-box { background: #111827; color: #10b981; font-family: monospace; font-size: 11px; height: 200px; overflow-y: auto; padding: 10px; border-radius: 6px; }
    .log-entry { margin-bottom: 4px; border-bottom: 1px solid #374151; padding-bottom: 2px; }
    .log-time { color: #6b7280; margin-right: 5px; }
    .error { color: #ef4444; }
    .info { color: #60a5fa; }
    .success { color: #34d399; }

    .progress-container { background: #e5e7eb; height: 8px; border-radius: 4px; margin: 10px 0; overflow: hidden; }
    .progress-bar { height: 100%; background: #7c3aed; width: 0%; transition: width 0.3s; }
    
    .row-item { padding: 5px; border-bottom: 1px solid #eee; display: flex; align-items: center; }
    .row-list { max-height: 150px; overflow-y: auto; border: 1px solid #eee; margin-bottom: 10px; }
  </style>
</head>
<body>
  
  <div class="card">
    <div class="header">STATUS</div>
    <div style="display:flex; justify-content:space-between; font-size:12px;">
      <span id="status-text">Idle</span>
      <span id="progress-text">0%</span>
    </div>
    <div class="progress-container">
      <div id="progress-bar" class="progress-bar"></div>
    </div>
    <div id="current-task" style="font-size:11px; color:#6b7280; font-style:italic; height:16px;"></div>
  </div>

  <div class="card">
    <div class="header">Select Rows</div>
    <div id="loading-rows">Loading rows...</div>
    <div id="row-list" class="row-list" style="display:none;"></div>
    <button onclick="startGeneration()" id="start-btn" class="btn btn-primary">▶ START GENERATION</button>
    <button onclick="stopGeneration()" id="stop-btn" class="btn btn-stop" style="display:none;">⏹ STOP</button>
  </div>

  <div class="card">
    <div class="header">Live Logs</div>
    <div id="logs" class="log-box"></div>
  </div>

  <script>
    let selectedRows = [];
    let isRunning = false;
    let pollInterval;

    function init() {
      loadRows();
      // Start polling immediately for state updates
      pollInterval = setInterval(pollState, 1500);
    }

    function loadRows() {
      google.script.run.withSuccessHandler(rows => {
        const list = document.getElementById('row-list');
        list.innerHTML = '';
        document.getElementById('loading-rows').style.display = 'none';
        list.style.display = 'block';

        if(rows.length === 0) {
            list.innerHTML = '<div style="padding:10px">No keywords found in Column A</div>';
            return;
        }

        rows.forEach(r => {
          const div = document.createElement('div');
          div.className = 'row-item';
          div.innerHTML = \`<input type="checkbox" value="\${r.row}" onchange="toggleRow(this)"> \${r.keyword}\`;
          list.appendChild(div);
        });
      }).getAvailableRows();
    }

    function toggleRow(cb) {
      const val = parseInt(cb.value);
      if(cb.checked) selectedRows.push(val);
      else selectedRows = selectedRows.filter(r => r !== val);
      document.getElementById('start-btn').innerText = \`▶ START GENERATION (\${selectedRows.length})\`;
    }

    function startGeneration() {
      if(selectedRows.length === 0) return alert('Select at least one row');
      
      document.getElementById('start-btn').disabled = true;
      document.getElementById('start-btn').style.display = 'none';
      document.getElementById('stop-btn').style.display = 'block';
      
      google.script.run.withSuccessHandler(res => {
         if(!res.success) alert(res.message);
      }).startGeneration(selectedRows);
    }

    function stopGeneration() {
       google.script.run.stopGeneration();
    }

    function pollState() {
      // 1. Get Logs
      google.script.run.withSuccessHandler(logs => {
        const div = document.getElementById('logs');
        // Simple diff check could go here, but rewriting is safer for sync
        const html = logs.map(l => 
          \`<div class="log-entry \${l.level}">
            <span class="log-time">[\${l.timestamp}]</span> \${l.message}
           </div>\`
        ).reverse().join(''); // Show newest first
        
        if(div.innerHTML !== html) div.innerHTML = html;
      }).getLogs();

      // 2. Get Status
      google.script.run.withSuccessHandler(state => {
        document.getElementById('status-text').innerText = state.isProcessing ? 'Processing...' : 'Idle';
        document.getElementById('progress-bar').style.width = state.progress + '%';
        document.getElementById('progress-text').innerText = state.progress + '%';
        document.getElementById('current-task').innerText = state.currentTask;

        if(!state.isProcessing) {
           document.getElementById('start-btn').disabled = false;
           document.getElementById('start-btn').style.display = 'block';
           document.getElementById('stop-btn').style.display = 'none';
        } else {
           document.getElementById('start-btn').style.display = 'none';
           document.getElementById('stop-btn').style.display = 'block';
        }
      }).getProcessingStatus();
    }

    window.onload = init;
  </script>
</body>
</html>
  `;
}